﻿using PaperMaster.Chess.ChessModel;
using PaperMaster.Utility.Controller;
using UnityEngine;
using PaperMaster.Model;
using PaperMaster.Chess.Bell;
using PaperMaster.Chess.PieceSpace;
using UnityEngine.UI;
using System.Collections.Generic;
using PaperMaster.Info;
using PaperMaster.Chess.Enemy;
using PaperMaster.Chess.PlayerCore;

namespace PaperMaster.Chess
{
    public class ChessBoardController : Controller,IFightBeginCommand,IFightEndCommand
    {
        public static ChessBoardController GetController()
        {
            GameObject obj = GameObject.Find("ChessBoard");
            if (obj != null)
            {
                return obj.GetComponent<ChessBoardViewController>().controller;
            }
            return null;
        }
        public IChessModel model;
        public ChessBoardController()
        {
            Init();
        }

        protected override void Init()
        {
            model = ModelContainer.Get<IChessModel>();
            InitBoard();
            base.Init();
        }
        /// <summary>
        /// 设置物块的位置
        /// </summary>
        void InitBoard()
        {
            Transform boardTransform = model.Board.boardObject.transform;
            for(int i = 0; i < model.BoardWidth; i++)
            {
                for(int j = 0; j < model.BoardLength; j++)
                {
                    Transform blockObject = boardTransform.GetChild(i * model.BoardLength + j);
                    ChessBlockModel m = model.Board.v[i][j];
                    m.pos3d = blockObject.position;
                    m.pos2d = new Vector2Int(j, i);
                    m.viewController = blockObject.gameObject.GetComponent<ChessBlock>();
                    ChessBlock block = m.viewController;
                    if (block.controller == null)
                    {
                        block.controller = new ChessBlockController();
                    }
                    block.controller.model = model.Board.v[i][j];
                }
            }
        }
        protected override void RegisterEvents()
        {
            PlayerTurnBeginEvent.Register(OnPlayerTurnStart);
            PlayerTurnEndEvent.Register(OnPlayerTurnEnd);
        }
        ~ChessBoardController()
        {
        }

        #region 响应函数
        /// <summary>
        /// 
        /// </summary>
        void OnFightStart()
        {
            GetMap();
            GetEnemy();
        }
        void OnFightEnd()
        {

        }

        void OnPlayerTurnStart()
        {
            ChessBlockModel[][] v = model.Board.v;
            for(int i = 0; i < v.Length; i++)
            {
                for(int j = 0; j < v[0].Length; j++)
                {
                    if (v[i][j].Piece!=null)
                    {
                        if (v[i][j].Piece.model.owner == PieceSpace.PieceOwner.Player)
                        {
                            if (!((PieceModelBase)(v[i][j].Piece.model)).BeginMoved)
                            {
                                v[i][j].Piece.BeginAct();
                            }
                        }
                        else
                        {
                            if (!((PieceModelBase)(v[i][j].Piece.model)).Moved)
                            {
                                v[i][j].Piece.EndAct();
                            }
                        }
                    }
                }
            }
        }

        void OnPlayerTurnEnd()
        {
            ChessBlockModel[][] v = model.Board.v;
            for (int i = 0; i < v.Length; i++)
            {
                for (int j = 0; j < v[0].Length; j++)
                {
                    if (v[i][j].Piece != null)
                    {
                        if (v[i][j].Piece.model.owner == PieceSpace.PieceOwner.Player)
                        {
                            if (!((PieceModelBase)(v[i][j].Piece.model)).Moved)
                            {
                                v[i][j].Piece.EndAct();
                            }
                        }
                        else
                        {
                            if (!((PieceModelBase)(v[i][j].Piece.model)).BeginMoved)
                            {
                                v[i][j].Piece.BeginAct();
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 获取并设置地图
        /// </summary>
        void GetMap()
        {
            model.Board.v[0][0] = new ChessBlockModel(ChessBlockType.None, ElementType.Water);
            model.Board.Invoke();
        }
        /// <summary>
        /// 获取并设置敌人
        /// </summary>
        void GetEnemy()
        {

        }

        public void FightBeginExecute()
        {
            OnFightStart();
        }
        public void FightEndExecute()
        {
            OnFightEnd();
        }

        #endregion
        #region 接口
        /// <summary>
        /// 在棋盘上某处放置一个棋子，若放置成功则返回true，否则返回false
        /// </summary>
        /// <param name="lable">棋子</param>
        /// <param name="loc">位置</param>
        /// <returns></returns>
        public bool AddPiece(Piece label,PieceOwner owner,Vector2Int loc)
        {
            if (model.Board.v[loc.y][loc.x].Piece != null)
            {
                return false;
            }
            GameObject piece=model.pieceFactory.Produce(label, owner);
            PieceControllerBase controller = piece.GetComponent<PieceViewController>().controller;
            model.Board.v[loc.y][loc.x].Piece = controller;
            return true;
        }
        /// <summary>
        /// 将from处的棋子移动到to处，移动成功则返回true，否则返回false
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        public bool MovePieceTo(Vector2Int from,Vector2Int to)
        {
            PieceControllerBase controller = model.Board.v[from.y][from.x].Piece;
            if (controller == null)
            {
                return false;
            }
            if (model.Board.v[to.y][to.x].Piece != null)
            {
                return false;
            }
            model.Board.v[to.y][to.x].Piece = controller;
            return true;
        }
        /// <summary>
        /// 在棋盘的某个位置试着放下一个棋子，若失败则会返回false
        /// </summary>
        /// <returns></returns>
        public bool SetPiece(Piece label, PieceOwner owner, Vector2Int pos)
        {
            if (pos.x < 0 || pos.x >= model.BoardLength || pos.y < 0 || pos.y >= model.BoardWidth)
            {
                return false;
            }
            ChessBlockModel block = model.Board.v[pos.y][pos.x];
            if (block.Piece != null)
            {
                return false;
            }
            Transform piece = model.pieceFactory.Produce(label, owner).transform;
            piece.position = block.pos3d;
            block.Piece = piece.GetComponent<PieceViewController>().controller;
            block.Piece.model.Loc = block.pos2d;
            block.Piece.model.owner = owner;
            if (owner == PieceOwner.Opponent)
            {
                piece.Rotate(new Vector3(0, 180, 0));
            }
            return true;
        }
        /// <summary>
        /// 在选中的位置处试着放一个棋子
        /// </summary>
        /// <param name="label"></param>
        /// <param name="owner"></param>
        /// <returns></returns>
        public bool SetPiece(Piece label,PieceOwner owner)
        {
            ChessBlockModel selectedBlock = model.Board.selectedBlock;
            if (selectedBlock == null)
            {
                return false;
            }
            Vector2Int pos = selectedBlock.pos2d;
            ChessBlockModel block = model.Board.v[pos.y][pos.x];
            if (block.Piece != null)
            {
                return false;
            }
            Transform piece = model.pieceFactory.Produce(label, owner).transform;
            piece.position = block.pos3d;
            block.Piece = piece.GetComponent<PieceViewController>().controller;
            block.Piece.model.Loc = block.pos2d;
            return true;
        }
        /// <summary>
        /// 选中棋盘上某个位置，将显示对应信息
        /// </summary>
        public void SelectBlock(Vector2Int pos)
        {
            ChessBlockModel block = model.Board.v[pos.y][pos.x];
            AbstractFightInfoViewController.GetController().UpdateUI("Block");
        }
        /// <summary>
        /// 释放一个Attack的效果
        /// </summary>
        /// <param name="atk"></param>
        public void GiveAtk(IAttack atk)
        {
            List<Vector2Int> scope = atk.scopeOfAttack;
            foreach (var pos in scope)
            {
                if (atk.owner == PieceOwner.Player && pos.y >= model.BoardWidth)
                {
                    EnemyViewController.GetController().TakeDamage(atk);
                }
                else if (atk.owner == PieceOwner.Opponent && pos.y < 0)
                {
                    PlayerCoreViewController.GetController().TakeDamage(atk);
                }
                else
                {
                    PieceControllerBase piece = model.Board.v[pos.y][pos.x].Piece;
                    if (piece != null
                        &&
                        (piece.model.owner != atk.owner
                        || piece.model.owner == PieceOwner.Env))
                    {
                        piece.TakeAttack(atk);
                    }
                }
            }
        }
        #endregion
    }
}
